home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / mg / gl / mggldraw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-06  |  10.7 KB  |  461 lines

  1. /* Copyright (c) 1992 The Geometry Center; University of Minnesota
  2.    1300 South Second Street;  Minneapolis, MN  55454, USA;
  3.    
  4. This file is part of geomview/OOGL. geomview/OOGL is free software;
  5. you can redistribute it and/or modify it only under the terms given in
  6. the file COPYING, which you should have received along with this file.
  7. This and other related software may be obtained via anonymous ftp from
  8. geom.umn.edu; email: software@geom.umn.edu. */
  9.  
  10. /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
  11.  
  12. #include "mgP.h"
  13. #include "mgglP.h"
  14. #include "polylistP.h"
  15. #include <gl/gl.h>
  16.  
  17. void    mggl_polygon( int nv, HPoint3 *v, int nn, Point3 *n,
  18.                         int nc,ColorA *c );
  19. void    mggl_mesh( int wrap,int nu,int nv,HPoint3 *p, Point3 *n,ColorA *c );
  20. void    mggl_line( HPoint3 *p1, HPoint3 *p2 );
  21. void    mggl_polyline( int nv, HPoint3 *verts, int nc, ColorA *colors, int wrap );
  22. void    mggl_polylist(  int np, Poly *p, int nv, Vertex *v, 
  23.                  int plflags );
  24. void    mggl_drawnormal(HPoint3 *p, Point3 *n);
  25.  
  26. void    mggl_closer();
  27. void    mggl_farther();
  28.  
  29. /*-----------------------------------------------------------------------
  30.  * Function:    mggl_polygon
  31.  * Description:    draw a polygon
  32.  * Author:    mbp, munzner
  33.  * Date:    Mon Jul 29 16:53:56 1991
  34.  * Notes:    See mg.doc.
  35.  *
  36.  *              do later: Different shading cases separated into different
  37.  *        loops for speed.
  38.  */
  39. void
  40. mggl_polygon(int nv,  HPoint3 *V, 
  41.          int nn,  Point3 *N, 
  42.          int nc,  ColorA *C)
  43. {
  44.   register int i;    
  45.   register HPoint3 *v;
  46.   register Point3 *n;
  47.   register ColorA *c;
  48.   int cinc, ninc;
  49.   int flag;
  50.  
  51.   flag = _mgc->astk->ap.flag;
  52.   if ((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader)
  53.     nc = 0;
  54.   cinc = (nc > 1);
  55.   ninc = (nn > 1);
  56.   if(nc == 0)
  57.     C = (ColorA*)&_mgc->astk->ap.mat->diffuse;
  58.  
  59.  
  60.   /* reestablish correct drawing color if necessary */
  61.  
  62.   if (flag & APF_FACEDRAW) {
  63.     lmcolor(_mgglc->lmcolor);
  64.     bgnpolygon();
  65.     if (nc <= 1)
  66.     (*_mgglc->d4f)(&(_mgc->astk->ap.mat->diffuse));
  67.     for (n = N, c = C, v = V, i = 0; i<nv; ++i, ++v) {
  68.     if (nc) { (*_mgglc->d4f)(c); c += cinc; }
  69.     if (nn) { (*_mgglc->n3f)(n,v); n += ninc; }
  70.     v4f((float *)v);
  71.     }
  72.     endpolygon();
  73.   }
  74.  
  75.   if( flag & (APF_EDGEDRAW|APF_NORMALDRAW) ) {
  76.     if(_mgglc->znudge) mggl_closer();
  77.     lmcolor(LMC_COLOR);
  78.     if (flag & APF_EDGEDRAW) {
  79.     c3f((float *)&_mgc->astk->ap.mat->edgecolor);
  80.     bgnclosedline();
  81.     for (v = V, i = 0; i<nv; ++i, ++v)
  82.       v4f((float *)v);
  83.     endclosedline();
  84.     }
  85.  
  86.     if (flag & APF_NORMALDRAW) {
  87.     c3f((float *)&_mgc->astk->ap.mat->normalcolor);
  88.     for (n = N, v = V, i = 0; i<nv; ++i, ++v, n += ninc) {
  89.         mggl_drawnormal(v, n);
  90.     }
  91.     }
  92.     if(_mgglc->znudge) mggl_farther();
  93.   }
  94. }
  95.  
  96. void
  97. mggl_quads(int count,  HPoint3 *V, Point3 *N, ColorA *C)
  98. {
  99.   int i;    
  100.   register int k;
  101.   register HPoint3 *v;
  102.   register Point3 *n;
  103.   register ColorA *c;
  104.   ColorA cs[4];
  105.   int flag;
  106.  
  107. #define QUAD(stuff)  { \
  108.         register int k = 4;        \
  109.         bgnpolygon();            \
  110.         do { stuff; } while(--k > 0);    \
  111.         endpolygon();            \
  112.     }
  113.  
  114.   if(count <= 0)
  115.     return;
  116.   flag = _mgc->astk->ap.flag;
  117.   if ((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader)
  118.     C = NULL;
  119.   
  120.   /* reestablish correct drawing color if necessary */
  121.  
  122.   if (flag & APF_FACEDRAW) {
  123.     lmcolor(_mgglc->lmcolor);
  124.     i = count;
  125.     v = V; c = C; n = N;
  126.     if(c) {
  127.     if(n) {
  128.         do {
  129.         QUAD( ((*_mgglc->d4f)(c++), (*_mgglc->n3f)(n++,v),
  130.                     v4f((float*)v++)) );
  131.         } while(--i > 0);
  132.     } else {
  133.         /* Colors, no normals */
  134.         do {
  135.         QUAD( ((*_mgglc->d4f)(c++), v4f((float*)v++)) );
  136.         } while(--i > 0);
  137.     }
  138.     } else {
  139.     c = (ColorA*)&_mgc->astk->ap.mat->diffuse;
  140.     if(n) {
  141.         (*_mgglc->d4f)(c);
  142.         do {
  143.         QUAD( ((*_mgglc->n3f)(n++, v), v4f((float*)v++)) );
  144.         } while(--i > 0);
  145.     } else {
  146.         (*_mgglc->d4f)(c);
  147.         do {
  148.         QUAD( (v4f((float*)v++)) );
  149.         } while(--i > 0);
  150.     }
  151.     }
  152.   }
  153.  
  154.   if( flag & (APF_EDGEDRAW|APF_NORMALDRAW) ) {
  155.     if(_mgglc->znudge) mggl_closer();
  156.     lmcolor(LMC_COLOR);
  157.     if (flag & APF_EDGEDRAW) {
  158.     c3f((float *)&_mgc->astk->ap.mat->edgecolor);
  159.     i = count; v = V;
  160.     do {
  161.         register int k = 4;
  162.         bgnclosedline();
  163.         do { v4f((float *)v++); } while(--k > 0);
  164.         endclosedline();
  165.     } while(--i > 0);
  166.     }
  167.  
  168.     if (flag & APF_NORMALDRAW && N) {
  169.     c3f((float *)&_mgc->astk->ap.mat->normalcolor);
  170.     i = count*4; v = V; n = N;
  171.     do {
  172.         mggl_drawnormal(v++, n++);
  173.     } while(--i > 0);
  174.     }
  175.     if(_mgglc->znudge) mggl_farther();
  176.   }
  177. }
  178.  
  179.  
  180. void mggl_line( HPoint3 *p1, HPoint3 *p2 )
  181. {
  182.   bgnline();
  183.   v4f((float *)p1);
  184.   v4f((float *)p2);
  185.   endline();
  186. }
  187.  
  188. void mggl_point(register HPoint3 *v)
  189. {
  190.   int i;
  191.   HPoint3 a;
  192.   register HPoint3 *p, *q;
  193.   float vw;
  194.  
  195.   if(_mgc->astk->ap.linewidth > 1) {
  196.     
  197.     if(!(_mgc->has & HAS_POINT))
  198.       mg_makepoint();
  199.     /* Compute w component of point after projection to screen */
  200.     vw = v->x * _mgc->O2S[0][3] + v->y * _mgc->O2S[1][3]
  201.       + v->z * _mgc->O2S[2][3] + v->w * _mgc->O2S[3][3];
  202.     if(vw <= 0) return;
  203.     
  204. #define  PUT(p)                      \
  205.     a.x = v->x + p->x*vw; a.y = v->y + p->y*vw;    \
  206.       a.z = v->z + p->z*vw; a.w = v->w + p->w*vw;    \
  207.     v4f((float *)&a)
  208.       
  209.       p = VVEC(_mgc->point, HPoint3);
  210.     q = p + VVCOUNT(_mgc->point);
  211.     
  212.     if(_mgglc->is_PI) {
  213.       bgnpolygon();
  214.       do {
  215.     PUT(p);
  216.       } while(++p < q);
  217.       endpolygon();
  218.     } else {
  219.       bgntmesh();
  220.       PUT(p);
  221.       do {
  222.     p++;
  223.     PUT(p);
  224.     if(p >= q) break;
  225.     q--;
  226.     PUT(q);
  227.       } while(p < q);
  228.       endtmesh();
  229.     }
  230.   } else {
  231.     bgnpoint();
  232.     v4f((float *)v);
  233.     endpoint();
  234.   }
  235. }
  236.   
  237.  
  238. void mggl_polyline( int nv, HPoint3 *v, int nc, ColorA *c, int wrapped )
  239. {
  240.   int remain;
  241.  
  242.   /* note we don't reset to current material color because we could be
  243.    * in the middle of a list of lines and should inherit the color from 
  244.    * the last color call.
  245.    */
  246.   
  247.   if(!(wrapped & 2)) {
  248.     /* First member of batch */
  249.       if(_mgglc->znudge) mggl_closer();
  250.       if(nc)
  251.       lmcolor(LMC_COLOR);
  252.   }
  253.   if (nv == 1) {
  254.     if(nc > 0) c4f((float *)c);
  255.     mggl_point(v);
  256.   } 
  257.   else if(nv > 0) {
  258.     bgnline();
  259.     if(wrapped & 1) {
  260.       if(nc > 0) c4f((float *)(c + nc - 1));
  261.       v4f((float *)(v + nv - 1));
  262.     }
  263.  
  264.     for(;;) {
  265.     remain = nv > 254 ? 254 : nv;
  266.     nv -= remain;
  267.     do {
  268.         if(--nc >= 0) c4f((float *)c++);
  269.         v4f((float *)v++);
  270.     } while(--remain > 0);
  271.     if(nv == 0)
  272.         break;
  273.     if(nc > 0) c4f((float *)c);
  274.     v4f((float *)v);
  275.     endline();
  276.     bgnline();
  277.     }
  278.     endline();
  279.   }
  280.   if(!(wrapped & 4) && _mgglc->znudge) mggl_farther();
  281. }
  282.  
  283.  
  284. /*-----------------------------------------------------------------------
  285.  * Function:    mggl_polylist
  286.  * Description:    draws a Polylist: collection of Polys
  287.  * Author:    munzner
  288.  * Date:    Wed Oct 16 20:21:56 1991
  289.  * Notes:    see mg.doc
  290.  */
  291. void mggl_polylist( int np, Poly *_p, int nv, Vertex *V, int plflags )
  292. {
  293.   register int i,j;
  294.   register Poly *p;
  295.   register Vertex **v, *vp;
  296.   register Point3 *n;
  297.   struct mgastk *ma = _mgc->astk;
  298.   void (*n3func)() = _mgglc->n3f;
  299.   int flag,shading;
  300.   int nonsurf = -1;
  301.   flag = ma->ap.flag;
  302.   shading = ma->ap.shading;
  303.  
  304.   switch(shading) {
  305.   case APF_FLAT: plflags &= ~PL_HASVN; break;
  306.   case APF_SMOOTH: plflags &= ~PL_HASPN; break;
  307.   default: plflags &= ~(PL_HASVN|PL_HASPN); break;
  308.   }
  309.  
  310.   if((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader)
  311.     plflags &= ~(PL_HASVCOL | PL_HASPCOL);
  312.  
  313.   if (flag & APF_FACEDRAW) {
  314.     lmcolor(_mgglc->lmcolor);
  315.     /* reestablish correct drawing color if necessary*/
  316.     if (!(plflags & (PL_HASPCOL | PL_HASVCOL)))
  317.     (*_mgglc->d4f)(&(ma->ap.mat->diffuse));
  318.  
  319.     for (p = _p, i = 0; i < np; i++, p++) {
  320.     if (plflags & PL_HASPCOL)
  321.         (*_mgglc->d4f)(&p->pcol);
  322.     if (plflags & PL_HASPN)
  323.         (*n3func)(&p->pn, &(*p->v)->pt);
  324.     v = p->v;
  325.     if((j = p->n_vertices) <= 2) {
  326.         nonsurf = i;
  327.     } else {
  328.         bgnpolygon();
  329.         do {
  330.         if (plflags & PL_HASVCOL) (*_mgglc->d4f)(&(*v)->vcol);
  331.         if (plflags & PL_HASVN) (*n3func)(&(*v)->vn, &(*v)->pt);
  332.         v4f((float *)&(*v)->pt);
  333.         v++;
  334.         } while(--j > 0);
  335.         endpolygon();
  336.     }
  337.     }
  338.   }
  339.  
  340.   if (flag & (APF_EDGEDRAW|APF_NORMALDRAW) || nonsurf >= 0) {
  341.     if(_mgglc->znudge) mggl_closer();
  342.     lmcolor(LMC_COLOR);
  343.  
  344.     if (flag & APF_EDGEDRAW) {
  345.     c3f((float *)&_mgc->astk->ap.mat->edgecolor);
  346.     for (p = _p, i = 0; i < np; i++, p++) {
  347.         bgnclosedline();
  348.         for (j=0, v=p->v; j < p->n_vertices; j++, v++) {
  349.         v4f((float *)&(*v)->pt);
  350.         }
  351.         endclosedline();
  352.     }
  353.     }
  354.  
  355.     if (flag & APF_NORMALDRAW) {
  356.     c3f((float *)&_mgc->astk->ap.mat->normalcolor);
  357.     if (plflags & PL_HASPN) {
  358.         for (p = _p, i = 0; i < np; i++, p++) {
  359.         for (j=0, v=p->v; j < p->n_vertices; j++, v++)
  360.           mggl_drawnormal(&(*v)->pt, &p->pn);
  361.         }
  362.     } else if (plflags & PL_HASVN) {
  363.         for (vp = V, i = 0; i < nv; i++, vp++) {
  364.         mggl_drawnormal(&vp->pt, &vp->vn);
  365.         }
  366.     }
  367.     }
  368.  
  369.  
  370.     if (nonsurf >= 0) {
  371.       /* reestablish correct drawing color if necessary*/
  372.       if (!(plflags & (PL_HASPCOL | PL_HASVCOL)))
  373.     (*_mgglc->d4f)(&(ma->ap.mat->diffuse));
  374.       
  375.       for(p = _p, i = 0; i <= nonsurf; p++, i++) {
  376.     if (plflags & PL_HASPCOL)
  377.       (*_mgglc->d4f)(&p->pcol);
  378.     v = p->v;
  379.     switch(j = p->n_vertices) {
  380.     case 1:
  381.       if(plflags & PL_HASVCOL) c4f((float *)&(*v)->vcol);
  382.       mggl_point(&(*v)->pt);
  383.       break;
  384.     case 2:
  385.       bgnline();
  386.       do {
  387.         if(plflags & PL_HASVCOL) c4f((float *)&(*v)->vcol);
  388.         v4f((float *)&(*v)->pt);
  389.         v++;
  390.       } while(--j > 0);
  391.       endline();
  392.       break;
  393.     }
  394.       }
  395.     }
  396.     if(_mgglc->znudge) mggl_farther();
  397.   }
  398. }
  399.  
  400. /*
  401.  * Z-shift routines: for moving edges closer than faces, etc.
  402.  */
  403. mggl_init_zrange()
  404. {
  405.   register struct mgglcontext *gl = _mgglc;
  406.  
  407.   gl->znudge = _mgc->zfnudge * (gl->zmax - gl->zmin);
  408.  
  409.   gl->znear = gl->zmin + abs(gl->znudge * MAXZNUDGE);
  410.   gl->zfar = gl->zmax - abs(gl->znudge * MAXZNUDGE);
  411.   lsetdepth(gl->znear, gl->zfar);
  412. }
  413.  
  414. void
  415. mggl_closer()
  416. {
  417.   lsetdepth( _mgglc->znear -= _mgglc->znudge, _mgglc->zfar -= _mgglc->znudge );
  418. }
  419. void
  420. mggl_farther()
  421. {
  422.   lsetdepth( _mgglc->znear += _mgglc->znudge, _mgglc->zfar += _mgglc->znudge );
  423. }
  424.  
  425. /* There is a basic problem now with 4-d points and 3-d normal vectors.
  426. For now, we'll just ignore the 4-th coordinate of the point when 
  427. computing the tip of the normal vector.  This will work OK with all
  428. existing models, but for genuine 4-d points it won't work.  But,
  429. come to think of it, what is the correct interpretation of the
  430. normal vector when the points live in 4-d?
  431. */
  432. void
  433. mggl_drawnormal(register HPoint3 *p, Point3 *n)
  434. {
  435.   Point3 end, tp;
  436.   float scale;
  437.  
  438.   if (p->w <= 0.0) return;
  439.   if(p->w != 1) {
  440.     HPt3ToPt3(p, &tp);
  441.     p = (HPoint3 *)&tp;
  442.   }
  443.  
  444.   scale = _mgc->astk->ap.nscale;
  445.   if(_mgc->astk->ap.flag & APF_EVERT) {
  446.     register Point3 *cp = &_mgc->cpos;
  447.     if(!(_mgc->has & HAS_CPOS))
  448.     mg_findcam();
  449.     if((p->x-cp->x) * n->x + (p->y-cp->y) * n->y + (p->z-cp->z) * n->z > 0)
  450.     scale = -scale;
  451.   }
  452.  
  453.   end.x = p->x + scale*n->x;
  454.   end.y = p->y + scale*n->y;
  455.   end.z = p->z + scale*n->z;
  456.   bgnline();
  457.   v3f((float *)p);
  458.   v3f((float *)&end);
  459.   endline();
  460. }
  461.